#include "dxdiagcom.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(dxdiag);

HRESULT DxDiagCOM_Init(DxDiagCOM* pcom)
{
    HRESULT hr;
    DXDIAG_INIT_PARAMS initParams;

    pcom->prov = NULL;
    pcom->root = NULL;

    /* Initialize COM */
    hr = CoInitialize(NULL);
    if (FAILED(hr))
    {
        WINE_ERR("CoInitialize failed\n");
        return hr;
    }

    /* Create a provider instance */
    hr = CoCreateInstance(&CLSID_DxDiagProvider, NULL, CLSCTX_INPROC_SERVER, &IID_IDxDiagProvider, (LPVOID*) &pcom->prov);
    if (FAILED(hr))
    {
        WINE_ERR("CoCreateInstance failed\n");
        CoUninitialize();
        return hr;
    }

    /* Initialize the provider */
    ZeroMemory(&initParams, sizeof(DXDIAG_INIT_PARAMS));
    initParams.dwSize = sizeof(DXDIAG_INIT_PARAMS);
    initParams.dwDxDiagHeaderVersion = DXDIAG_DX9_SDK_VERSION;

    hr = IDxDiagProvider_Initialize(pcom->prov, &initParams);
    if (FAILED(hr))
    {
        WINE_ERR("IDxDiagProvider_Initialize failed\n");
        IDxDiagProvider_Release(pcom->prov);
        return hr;
    }

    /* Get the root container */
    hr = IDxDiagProvider_GetRootContainer(pcom->prov,&pcom->root);
    if (FAILED(hr))
    {
        WINE_ERR("IDxDiagProvider_GetRootContainer failed\n");
        return hr;
    }

    return hr;
}

HRESULT DxDiagCOM_GetContainer(IDxDiagContainer* source, LPCWSTR query, IDxDiagContainer** container)
{

    HRESULT hr;

    hr = IDxDiagContainer_GetChildContainer(source, query, container);
    if (FAILED(hr))
        WINE_ERR("IDxDiagContainer_GetChildContainer failed: %s\n", wine_dbgstr_w(query));
     return hr;
}

HRESULT DxDiagCOM_GetProperty(IDxDiagContainer* source, LPCWSTR query, VARIANT* pvar)
{

    HRESULT hr;

    hr = IDxDiagContainer_GetProp(source, query, pvar);
    if (FAILED(hr))
        WINE_ERR("IDxDiagContainer_GetProp failed: %s\n", wine_dbgstr_w(query));
     return hr;
}

BOOL DxDiagCOM_GetStringProperty(IDxDiagContainer* source, LPCWSTR query, LPWSTR* result)
{
    VARIANT var;
    LPWSTR temp;

    /* Get the property */
    if (FAILED(DxDiagCOM_GetProperty(source, query, &var)))
        return FALSE;

    /* Convert the variant */
    temp = V_BSTR(&var);

    /* Copy it to the result string */
    *result = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(lstrlenW(temp)+1));
    lstrcpyW(*result, temp);

    return TRUE;
}

BOOL DxDiagCOM_GetIntegerProperty(IDxDiagContainer* source, LPCWSTR query, int* result)
{
    VARIANT var;

    /* Get the property */
    if (FAILED(DxDiagCOM_GetProperty(source, query, &var)))
        return FALSE;

    /* Convert the variant */
    *result = V_INT(&var);

    return TRUE;
}

BOOL DxDiagCOM_GetBoolProperty(IDxDiagContainer* source, LPCWSTR query, BOOL* result)
{
    VARIANT var;

    /* Get the property */
    if (FAILED(DxDiagCOM_GetProperty(source, query, &var)))
        return FALSE;

    /* Convert the variant */
    *result = V_BOOL(&var);

    return TRUE;
}

BOOL DxDiagCOM_GetDwordProperty(IDxDiagContainer* source, LPCWSTR query, DWORD* result)
{
    VARIANT var;

    /* Get the property */
    if (FAILED(DxDiagCOM_GetProperty(source, query, &var)))
        return FALSE;

    /* Convert the variant */
    *result = V_UI4(&var);

    return TRUE;
}
